package com.tomato.dynamic.threadpool.core.support;

import com.tomato.dynamic.threadpool.common.queue.ThreadPoolInfo;
import com.tomato.dynamic.threadpool.common.util.CalculateUtil;
import com.tomato.dynamic.threadpool.core.thread.DynamicThreadPoolExecutor;

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池信息构建器
 *
 * @author lizhifu
 * @date 2022/4/8
 */
public class ThreadPoolInfoBuilder {
    /**
     * 线程池
     */
    private ThreadPoolExecutor threadPoolExecutor;

    private ThreadPoolInfoBuilder(ThreadPoolExecutor threadPoolExecutor) {
        this.threadPoolExecutor = threadPoolExecutor;
    }
    private ThreadPoolInfoBuilder() {}

    public static ThreadPoolInfoBuilder newBuilder(ThreadPoolExecutor threadPoolExecutor) {
        return new ThreadPoolInfoBuilder(threadPoolExecutor);
    }
    public ThreadPoolInfo buildBase() {
        ThreadPoolInfo threadPoolInfo = new ThreadPoolInfo();
        // 核心线程数
        int corePoolSize = threadPoolExecutor.getCorePoolSize();
        // 最大线程数
        int maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();

        threadPoolInfo.setCorePoolSize(corePoolSize);
        threadPoolInfo.setMaximumPoolSize(maximumPoolSize);

        long rejectCount = threadPoolExecutor instanceof DynamicThreadPoolExecutor
                ? ((DynamicThreadPoolExecutor) threadPoolExecutor).getRejectCount()
                : -1L;
        threadPoolInfo.setRejectCount(rejectCount);

        RejectedExecutionHandler rejectedExecutionHandler = threadPoolExecutor instanceof DynamicThreadPoolExecutor
                ? ((DynamicThreadPoolExecutor) threadPoolExecutor).getRedundancyHandler()
                : threadPoolExecutor.getRejectedExecutionHandler();

        threadPoolInfo.setRejectedExecutionHandlerName(rejectedExecutionHandler.getClass().getSimpleName());

        int runTimeoutCount = threadPoolExecutor instanceof DynamicThreadPoolExecutor
                ? ((DynamicThreadPoolExecutor) threadPoolExecutor).getRunTimeoutCount()
                : -1;

        int queueTimeoutCount = threadPoolExecutor instanceof DynamicThreadPoolExecutor
                ? ((DynamicThreadPoolExecutor) threadPoolExecutor).getQueueTimeoutCount()
                : -1;
        threadPoolInfo.setRunTimeoutCount(runTimeoutCount);
        threadPoolInfo.setQueueTimeoutCount(queueTimeoutCount);

        return threadPoolInfo;
    }

    public ThreadPoolInfo build() {
        ThreadPoolInfo threadPoolInfo = buildBase();
        // 线程池当前线程数 (有锁)
        int poolSize = threadPoolExecutor.getPoolSize();
        // 活跃线程数 (有锁)
        int activeCount = threadPoolExecutor.getActiveCount();
        // 同时进入池中的最大线程数 (有锁)
        int largestPoolSize = threadPoolExecutor.getLargestPoolSize();
        // 线程池中执行任务总数量 (有锁)
        long completedTaskCount = threadPoolExecutor.getCompletedTaskCount();
        // 当前负载
        String currentLoad = CalculateUtil.divide(activeCount, threadPoolInfo.getMaximumPoolSize()) + "";
        // 峰值负载
        String peakLoad = CalculateUtil.divide(largestPoolSize, threadPoolInfo.getMaximumPoolSize()) + "";

        threadPoolInfo.setPoolSize(poolSize);
        threadPoolInfo.setActiveCount(activeCount);
        threadPoolInfo.setLargestPoolSize(largestPoolSize);
        threadPoolInfo.setCompletedTaskCount(completedTaskCount);
        threadPoolInfo.setCurrentLoad(currentLoad);
        threadPoolInfo.setPeakLoad(peakLoad);

        return threadPoolInfo;
    }
}
